package com.manager.common.config;

import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.support.config.FastJsonConfig;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
import com.manager.common.interceptor.LoginInterceptor;
import com.manager.common.token.TokenInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.config.annotation.*;

import java.util.ArrayList;
import java.util.List;

@Configuration
public class WebConfig implements WebMvcConfigurer {

    private static final String[] resources = {
            "classpath:/resources/", "classpath:/static/", "classpath:/templates/", "classpath:/public/",
            "classpath:/META-INF/resources/","classpath:/resources/templates/","classpath:/resources/static/",
            "D:/lhj/upload"};

    @Autowired
    ArgumentResolver argumentResolver;

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/**")
                .addResourceLocations(resources)
                .setCachePeriod(0);
    }

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**") // 所有接口
                .allowCredentials(true) // 是否发送 Cookie
                .allowedOriginPatterns("*")
                .allowedMethods(new String[]{"GET", "POST", "PUT", "DELETE"}) // 支持方法
                .allowedHeaders("*")
                .maxAge(360000);
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new TokenInterceptor()).addPathPatterns("/**");
        registry.addInterceptor(new LoginInterceptor()).addPathPatterns("/**")
         .excludePathPatterns("/","/login/*","/assets/*","/uploadFiles/*");
    }

    @Override
    public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
        configurer.defaultContentType(MediaType.APPLICATION_JSON);
    }

    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        /*添加fastjson*/
        converters.add(fastJsonHttpMessageConverters(converters));
    }

    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
        resolvers.add(argumentResolver);
    }

    /**
     * 定义fastjson替代jackson，有些地方单独使用了fastjson所以无法使用fastjson做全局配置
     *
     * @return
     */
    private HttpMessageConverter fastJsonHttpMessageConverters(List<HttpMessageConverter<?>> converters) {
        /*排除掉Jackson*/
        for (int i = converters.size() - 1; i >= 0; i--) {
            if (converters.get(i) instanceof MappingJackson2HttpMessageConverter) {
                converters.remove(i);
            }
        }
        FastJsonHttpMessageConverter fastJsonHttpMessageConverter = new FastJsonHttpMessageConverter();
        /*自定义fastjson配置*/
        FastJsonConfig config = new FastJsonConfig();
        config.setSerializerFeatures(
                /*是否输出值为null的字段,默认为false,我们将它打开*/
                SerializerFeature.WriteMapNullValue,
                /*将Collection类型字段的字段空值输出为[]*/
                SerializerFeature.WriteNullListAsEmpty,
                /*将字符串类型字段的空值输出为空字符串*/
                SerializerFeature.WriteNullStringAsEmpty,
                /*将数值类型字段的空值输出为0*/
                SerializerFeature.WriteNullNumberAsZero,
                /*自定义日期格式*/
                SerializerFeature.WriteDateUseDateFormat,
                /*禁用循环引用*/
                SerializerFeature.DisableCircularReferenceDetect
        );
        fastJsonHttpMessageConverter.setFastJsonConfig(config);
        /*但是MappingJackson2HttpMessageConverter里面支持的MediaTypes为application/json*/
        List<MediaType> fastMediaTypes = new ArrayList<>();
        fastMediaTypes.add(MediaType.APPLICATION_JSON_UTF8);
        fastJsonHttpMessageConverter.setSupportedMediaTypes(fastMediaTypes);
        return fastJsonHttpMessageConverter;
    }

}
